package lol.clann.minecraft.springboot.api.bukkit.utils;

import org.bukkit.Bukkit;
import org.bukkit.Server;
import org.bukkit.command.CommandMap;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitTask;

import java.util.concurrent.Callable;
import java.util.concurrent.Future;

/**
 *
 * @author pyz
 * @date 2019/5/6 11:28 PM
 */
public interface ServerUtils {
    /**
     * 若当前不是在主线程,抛异常
     */
    default void requirePrimaryThreadStrict() {
        if (!Bukkit.isPrimaryThread()) {
            throw new IllegalStateException("requirePrimaryThread");
        }
    }

    /**
     * 若当前是在主线程,抛异常
     */
    default void requireNotPrimaryThreadStrict() {
        if (Bukkit.isPrimaryThread()) {
            throw new IllegalStateException("requireNotPrimaryThread");
        }
    }

    /**
     * 根据设置决定是否进行主线程判断
     */
    void requirePrimaryThread();

    /**
     * 根据设置决定是否进行主线程判断
     */
    void requireNotPrimaryThread();

    public CommandMap getCommandMap();

    /**
     * 获取NMSServer对象
     *
     * @param <T>
     * @return
     */
    public <T> T getNMSServer();

    /**
     * 服务器实时tps
     * @return
     */
    double getTps();

    default public Server getServer() {
        return Bukkit.getServer();
    }

    default Player getPlayer(String name) {
        Player player = Bukkit.getServer().getPlayer(name);
        if (player == null || !player.getName().equals(name)) {
            return null;
        }
        return player;
    }

    /**
     * 判断服务器是否还在运行
     *
     * 注:触发关服操作后,此方法会返回false
     *
     * @return
     */
    boolean isRunning();

    /**
     * 在主线程执行任务,并返回执行结果
     *
     * @param task
     * @param <T>
     * @return
     */
    <T> Future<T> callSyncMethod(Callable<T> task);

    /**
     * 取消指定的task
     * @param taskId
     */
    void cancelTask(int taskId);

    /**
     * Bukkit.getScheduler().runTask
     * @param task
     * @return
     * @throws IllegalArgumentException
     */
    BukkitTask runTask(Runnable task) throws IllegalArgumentException;

    /**
     * Bukkit.getScheduler().runTaskAsynchronously
     * @param task
     * @return
     * @throws IllegalArgumentException
     */
    BukkitTask runTaskAsynchronously(Runnable task) throws IllegalArgumentException;

    /**
     * Bukkit.getScheduler().runTaskLater
     * @param task
     * @return
     * @throws IllegalArgumentException
     */
    BukkitTask runTaskLater(Runnable task, long delay) throws IllegalArgumentException;

    /**
     * Bukkit.getScheduler().runTaskLaterAsynchronously
     * @param task
     * @return
     * @throws IllegalArgumentException
     */
    BukkitTask runTaskLaterAsynchronously(Runnable task, long delay) throws IllegalArgumentException;

    /**
     * Bukkit.getScheduler().runTaskTimer
     * @param task
     * @return
     * @throws IllegalArgumentException
     */
    BukkitTask runTaskTimer(Runnable task, long delay, long interval) throws IllegalArgumentException;

    /**
     * Bukkit.getScheduler().runTaskTimerAsynchronously
     * @param task
     * @return
     * @throws IllegalArgumentException
     */
    BukkitTask runTaskTimerAsynchronously(Runnable task, long delay, long interval) throws IllegalArgumentException;

}
